#
# Copyright 2010 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import logging
import urllib

from google.appengine.ext import db

class WatchedFeed(db.Model):
  hub = db.TextProperty()
  title = db.StringProperty()
  refresh = db.IntegerProperty()
  expiration = db.DateTimeProperty()
  verified = db.DateTimeProperty()
  created = db.DateTimeProperty(auto_now_add=True)

  def GetPageToDisplay(self, page_size, bookmark):
    """Returns a page of results with pointer to next (if any) """
    next = None
    if bookmark:
      lines = WatchedFeed.all().order('-title').filter(
        'title <=', bookmark).fetch(page_size + 1)
    else:
      lines = WatchedFeed.all().order('-title').fetch(page_size + 1)
    if len(lines) == (page_size + 1):
      next = urllib.quote(lines[-1].title)
      lines = lines[:page_size]
    return lines, next


""" Because feeds is in a module that is imported, AppEngine will not reset the
 value on each request. This means that we can cache data for the life of
 the instance rather than just for the life of the request."""
feeds = {}

class PSHBCache():
  """ Known feeds are cached in instance global data to minimize database
  accesses. Unless LoadFeeds is called on instance startup, feed data will be
  retrieved from the database just-in-time. Note: Once cached, a feed record
  will stay in memory until either the feed is explicitly unsubscribed from
  the instance or the instance is reloaded. This policy is non-optimal, but
  reasonable.
  """

  def AddFeed(self, url, hub="", title=""):
    """Adds a new feed to global feeds."""
    global feeds
    if url not in feeds:
      feeds[url] = {'hub': hub, 'title': title}
      logging.info("Feed added to cache: %s, %s" % (url, str(feeds[url])))

  def LoadFeeds(self):
    global feeds
    all_feeds = WatchedFeed.all()
    for feed in all_feeds:
      self.AddFeed(feed.key().name(), hub=feed.hub, title=feed.title)

  def DeleteFeed(self, url):
    global feeds
    if url in feeds:
      del feeds[url]

  def FindFeed(self, url):
    global feeds
    return feeds.get(url, None)

  def FeedIsWatched(self, doc_feed_url):
    if self.FindFeed(doc_feed_url):
      return True
    feed = WatchedFeed.get_by_key_name(doc_feed_url)
    if feed:
      self.AddFeed(feed.key().name(), hub=feed.hub, title=feed.title)
      return True
    else:
      return False

